﻿using Kinlo.Entitys;
using Kinlo.WebApi.Model;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using XCode;
using XingLucifer.IBase.Enums;

namespace Kinlo.WebApi.Controllers
{
    public class PlateDatas
    {

        Action<string, MessageLevelType> _log;
        public PlateDatas(Action<string, MessageLevelType> log)
        {
            _log = log;
        }
        public static int GetQuarterly(DateTime dateTime) => dateTime.Month switch
        {
            int p when p is >= 1 and < 4 => 1,
            int p when p is >= 4 and < 7 => 2,
            int p when p is >= 7 and < 10 => 3,
            int p when p is >= 10 and <= 12 => 4,
            _ => 1,
        };
        public PlateResponse Get(PlateRequest req)
        {
            var sw = new Stopwatch();
            sw.Start();
            var rsp = new PlateResponse();
            try
            {
                try
                {
                    //var reqRaw = Request.Content.ReadAsStringAsync();
                    _log?.Invoke($"【WEB服务】请求内容:{JsonConvert.SerializeObject(req)}", MessageLevelType.信息);
                    rsp.Key = req.Key;
                    rsp.TrayNo = req.TrayNo;
                    if (!string.IsNullOrEmpty(req.TrayNo))
                    {
                        //Int64 trayId = Plate.FindMax("TrayID", Plate._.TrayBarcode == req.TrayNo);
                   

                        var plates = Plate.FindAll(Plate._.TrayBarcode == req.TrayNo);

                        if (plates == null || plates.Count == 0)
                        {
                            DateTime startTime = DateTime.Now.AddDays(-10);
                            OCV.Meta.TableName = $"OCV_{startTime:yyyy}{GetQuarterly(startTime)}";
                            Precharge.Meta.TableName = $"Precharge_{startTime:yyyy}{GetQuarterly(startTime)}";
                            Plate.Meta.TableName = $"Plate_{startTime:yyyy} {GetQuarterly(startTime)}";

                            plates = Plate.FindAll(Plate._.TrayBarcode == req.TrayNo);
                        }

                            if (plates!=null&&plates.Count>0)
                        {
                            long trayId = plates.Max(p => p.TrayID);


                            var batts = Plate.FindAll(Plate._.TrayID == trayId);

                            //var trayId = DB.Query<string>($"select max(trayId) from plate where trayBarcode='{req.TrayNo}'").FirstOrDefault();
                            //var exp = $"where  trayId='{trayId}'";
                            //var batts = DB.GetListAsync<Plate>(exp).Result;
                            if (batts != null && batts.Count() > 0)
                            {
                                //var indexs = Enumerable.Range(1, 256);
                                //var datas = from i in indexs
                                //            join f in batts
                                //            on i equals f.SeqNo into items
                                //            from item in items.DefaultIfEmpty()
                                //            select new PlateItem
                                //            {
                                //                Position = i,
                                //                BatteryCode = item?.Barcode ?? "",
                                //                BatteryStatus = String.IsNullOrEmpty(item?.Barcode) ? 2 : 1
                                //            };
                                foreach (var batt in batts)
                                {
                                    var item = new PlateItem();
                                    item.Position = Convert.ToInt32((batt.RowNo - 1) * 16 + batt.ColNo);
                                    item.BatteryCode = batt?.Barcode ?? "";
                                    item.BatteryStatus = String.IsNullOrEmpty(batt?.Barcode) ? 2 : 1;
                                    rsp.Items.Add(item);
                                }
                                //var datas = Enumerable.Range(1, 256).Select(i =>
                                //{
                                //    var item = batts.FirstOrDefault(f => f.SeqNo == i);
                                //    return new PlateItem
                                //    {
                                //        Position = i,
                                //        BatteryCode = item?.Barcode ?? "",
                                //        BatteryStatus = item?.Barcode == null ? 2 : 1
                                //    };
                                //});
                                //rsp.Items.AddRange(rsp.Items);
                                rsp.CellBatch = batts.FirstOrDefault(s => !string.IsNullOrEmpty(s.CellBatch))?.CellBatch ?? "";
                                rsp.CellType = batts.FirstOrDefault(s => !string.IsNullOrEmpty(s.CellType))?.CellType ?? "";
                                rsp.Code = 1;
                            }
                            else
                            {
                                rsp.Code = 2;
                                rsp.Message = $"没有找到对应的装盘数据 {req.TrayNo}";
                            }
                        }
                        else
                        {
                            rsp.Code = 2;
                            rsp.Message = $"没有找到对应的装盘数据 {req.TrayNo}";
                        }

                    }
                }
                catch (Exception ex)
                {
                    rsp.Code = 3;
                    rsp.Message = ex.InnerException.Message ?? ex.Message;
                }
                return rsp;
            }
            finally
            {

                _log?.Invoke($"【WEB服务】耗时:{sw.ElapsedMilliseconds} 返回结果:{JsonConvert.SerializeObject(rsp)}", MessageLevelType.信息);
                sw.Reset();
            }
        }


        public PrechargeRsp AddPrechargeOCVData(PrechargeDto req)
        {
            var sw = new Stopwatch();
            sw.Start();
            var rsp = new PrechargeRsp();

            try
            {
                try
                {
                    _log?.Invoke($"【WEB服务】请求内容:{JsonConvert.SerializeObject(req)}", MessageLevelType.信息);
                    if (!string.IsNullOrEmpty(req.TrayCode))
                    {
                        //string table = req.ProcessNO.ToUpper().Contains("OCV0") ? "ocv" : "precharge";
                        string table = req.ProcessNO.ToUpper().Contains("OCV0") ? "OCV" : "Plate";

                        if (table.Contains("OCV"))
                        {

                            var ocvData = OCV.FindAll(OCV._.TrayCode == req.TrayCode);
                            ocvData.ToList().ForEach(item =>
                            {
                                item.Flag = 1;
                            });

                            ocvData.Update();
                        }
                        else
                        {
                            var prechargeData = Precharge.FindAll(OCV._.TrayCode == req.TrayCode);
                            prechargeData.ToList().ForEach(item =>
                            {
                                item.Flag = 1;
                            });

                            prechargeData.Update();
                        }

                        var tickId = DateTime.Now.Ticks;
                        var msg = "";
                        if (req.BatteryList.Count == 256)
                        {
                            //ProductionCounter.Tmp.Load();
                            var tableDataList = new List<OCV>();
                            for (int i = 0; i < req.BatteryList.Count; i++)
                            {
                                var batt = req.BatteryList[i];

                                var batt1 = new OCV
                                {
                                    TrayID = tickId,
                                    TrayCode = req.TrayCode,
                                    ProcessNO = req.ProcessNO,
                                    Flag = 0,
                                    //Position = i + 1,
                                    Position = batt.Position,
                                    BatteryCode = batt.BatteryCode,
                                    BatteryStatus = batt.BatteryStatus,
                                    NGCode = batt.NGCode,
                                    IR = batt.IR,
                                    Voltage = batt.Voltage,
                                    Steptype = batt.Steptype,
                                    Current = batt.Current,
                                    Capacity = batt.Capacity,
                                    Energy = batt.Energy,
                                };
                                tableDataList.Add(batt1);

                                //code = DB.Insert<OCV>(batt1);
                                //if (batt.BatteryStatus == 1)
                                //{
                                //    ProductionCounter.Tmp.OKCount++;
                                //}
                                //else if (batt.BatteryStatus == 2)
                                //{
                                //    ProductionCounter.Tmp.NGCount++;
                                //}
                                //else
                                //{
                                //    ProductionCounter.Tmp.NullCount++;
                                //}
                            }
                            int? code = -1;
                            if (table.Contains("OCV"))
                            {
                                code = tableDataList.Insert();

                            }
                            else
                            {
                                //code = DB.Insert<Precharge>(batt1.ToPrecharge());
                                code = ToPrechargeList(tableDataList).Insert();
                            }
                            if (code <= 0)
                            {
                                //$"【WEB服务】{batt1.BatteryCode}数据保存失败 {table}".Info("Log", LevelType.Info, false);

                                _log?.Invoke($"【WEB服务】{JsonConvert.SerializeObject(tableDataList)}数据保存失败 {table}", MessageLevelType.信息);
                                msg = "保存失败";
                            }

                            rsp.Message = "";
                            rsp.Code = 1;
                            //if (!string.IsNullOrEmpty(msg))
                            //{
                            //    rsp.Message = "数据保存失败";
                            //    rsp.Code = 2;
                            //}
                            //else
                            //{
                            //    rsp.Message = "";
                            //    rsp.Code = 1;
                            //}
                            //if (table == "ocv")
                            //ProductionCounter.Tmp.Save();
                        }
                        else
                        {
                            msg = $"数据条目不匹配 期待256,实际{req.BatteryList.Count} ";
                            rsp.Message = msg;
                            rsp.Code = 2;
                        }
                    }
                    else
                    {
                        rsp.Message = "托盘号不正确";
                        rsp.Code = 2;
                    }
                }
                catch (Exception ex)
                {
                    _log?.Invoke($"【WEB服务】服务发生异常:{ex}", MessageLevelType.信息);
                    //$"【WEB服务】服务发生异常:{ex}".Info("Log", LevelType.Info, false);
                    rsp.Code = 3;
                    rsp.Message = ex.InnerException.Message ?? ex.Message;
                }
                return rsp;
            }
            finally
            {
                _log?.Invoke($"【WEB服务】耗时:{sw.ElapsedMilliseconds} 返回结果:{JsonConvert.SerializeObject(rsp)}", MessageLevelType.信息);
                sw.Reset();
            }
        }

        public OCVResponse GetOCV(OCVRequest req)
        {
            var sw = new Stopwatch();
            sw.Start();
            var rsp = new OCVResponse();
            try
            {
                try
                {
                    //var reqRaw = Request.Content.ReadAsStringAsync();
                    //$"【WEB服务】请求内容:{JsonConvert.SerializeObject(reqRaw.Result)}".Info("Log", LevelType.Info, false);
                    //rsp.Key = req.Key;
                    //rsp.TrayNo = req.TrayNo;

                    _log?.Invoke($"【WEB服务】请求内容:{JsonConvert.SerializeObject(req)}", MessageLevelType.信息);
                    if (!string.IsNullOrEmpty(req.TrayNo))
                    {

                        //var trayId = OCV.FindMax("TrayID", OCV._.TrayCode == req.TrayNo);


                        var ocvs = OCV.FindAll(OCV._.TrayCode == req.TrayNo);
                        long trayId = ocvs.Max(p => p.TrayID);

                        var batts = OCV.FindAll(OCV._.TrayID == trayId).OrderBy(batt => batt.Position).ToList();

                        if (batts == null || batts.Count == 0)
                        {
                            DateTime startTime = DateTime.Now.AddDays(-10);
                            OCV.Meta.TableName = $"OCV_{startTime:yyyy}{GetQuarterly(startTime)}";
                            Precharge.Meta.TableName = $"Precharge_{startTime:yyyy}{GetQuarterly(startTime)}";
                            Plate.Meta.TableName = $"Plate_{startTime:yyyy} {GetQuarterly(startTime)}";
                            ocvs = OCV.FindAll(OCV._.TrayCode == req.TrayNo);
                            trayId = ocvs.Max(p => p.TrayID);
                            batts = OCV.FindAll(OCV._.TrayID == trayId).OrderBy(batt => batt.Position).ToList();
                        }
                        //var trayId = DB.Query<string>($"select max(trayId) from ocv where TrayCode='{req.TrayNo}'").FirstOrDefault();
                        //var exp = $"where  trayId='{trayId}'";
                        //var batts = DB.GetListAsync<OCV>(exp)
                        //.Result
                        //.OrderBy(batt => batt.Position)
                        //.ToList();
                        if (batts != null && batts.Count() > 0)
                        {
                            rsp.Message = ""; // 设置响应消息

                            foreach (var batt in batts)
                            {
                                var item = new OCVItem();
                                item.TrayCode = batt.TrayCode;
                                item.ProcessNo = batt.ProcessNO;
                                item.BatteryCode = batt.BatteryCode;
                                item.Position = batt.Position;
                                item.BatteryStatus = batt.BatteryStatus;
                                item.NGCode = batt.NGCode;
                                item.flag = batt.Flag;
                                rsp.Items.Add(item);
                            }

                            rsp.CellBatch = "";
                            rsp.CellType = "";
                            rsp.Code = 1;
                        }
                        else
                        {
                            rsp.Code = 2;
                            rsp.Message = $"没有找到对应的装盘数据 {req.TrayNo}";
                        }
                    }
                }
                catch (Exception ex)
                {
                    rsp.Code = 3;
                    rsp.Message = ex.InnerException.Message ?? ex.Message;
                }
                return rsp;
            }
            finally
            {
                _log?.Invoke($"【WEB服务】耗时:{sw.ElapsedMilliseconds} 返回结果:{JsonConvert.SerializeObject(rsp)}", MessageLevelType.信息);
                sw.Reset();
            }
        }

        public List<Precharge> ToPrechargeList(List<OCV> _ocv)
        {
            var dataList = new List<Precharge>();

            _ocv.ForEach(item =>
            {
                dataList.Add(new Precharge
                {
                    BatteryCode = item.BatteryCode,
                    BatteryStatus = item.BatteryStatus,
                    Flag = item.Flag,
                    NGCode = item.NGCode,
                    Position = item.Position,
                    ProcessNO = item.ProcessNO,
                    TrayCode = item.TrayCode,
                    TrayID = item.TrayID,

                    IR = item.IR,
                    Voltage = item.Voltage,
                    Steptype = item.Steptype,
                    Current = item.Current,
                    Capacity = item.Capacity,
                    Energy = item.Energy,
                });

            });

            return dataList;
        }

    }
}
